﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections;
using System.IO;
using System.Data.OleDb;

using System.Drawing.Drawing2D;
using ctdReader;
using DllnSpace;
using ctdFunction;

namespace JsRunTool
{

    public partial class Form1 : Form
    {
        //1.声明自适应类实例
        //AutoSizeFormClass asc = new AutoSizeFormClass();
        private float X;
        private float Y;

        static Form1 fm;
        public CardDllInterface m_card;
        public Script sc = new Script();

        Dictionary<string, string> myDictionary = new Dictionary<string, string>();

        public Form1()
        {
            InitializeComponent();
            m_card = new CardDllInterface();
            fm = this;
            m_card.form = this;
            CPublic.setCardDllInterface(ref m_card);
            CPublic.fm = this;

        }

        public void printRetData(string txt)
        {
            rtbRetStr.Text = txt;
        }

        public void printApdu(string txt)
        {
            if (txt.Contains("失败"))
            {
                rtbApdu.AppendTextColorful(txt, Color.Red, new Font("宋体", 20));
                rtbApdu.SelectionStart = rtbApdu.Text.Length - 1;
            }
            else
            {
                rtbApdu.AppendTextColorful(txt, Color.Green, new Font("宋体", 20));
                rtbApdu.SelectionStart = rtbApdu.Text.Length - 1;
            }
        }

        private void 设置读卡器ToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            FrmCardReaderConfig fmRead = new FrmCardReaderConfig();
            fmRead.ShowDialog();
        }

        private void 打开文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = true;
            fileDialog.Title = "请选择文件";
            fileDialog.Filter = "所有文件(*.*)|*.*";
            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = fileDialog.FileName;

                string tmpfilePath = fileDialog.FileName.ToLower();
                if (tmpfilePath.Contains(".js"))
                {
                    TreeNode node = tvFile.Nodes.Add(filePath);

                }
                else if (tmpfilePath.Contains(".dll"))
                {
                    
                    string[] funNames = DllnSpace.ParserDLLClass.getArrFunName(filePath);

                    TreeNode node = null; //tvFile.Nodes.Add(filePath);
                    string checkType = "";
                    for (int i = 0; i < funNames.Length; i++)
                    {
                        string funName = funNames[i];
                        
                        //判断函数名如果是 ctdCheck_xxx  则添加函数
                        
                        if (funName.ToLower().Contains("ctdcheck"))
                        {
                            string tmpType = funName.Split('_')[1];
                            
                            if (checkType.ToLower() != tmpType.ToLower())
                            {
                                node = tvFile.Nodes.Add(filePath);
                                checkType = tmpType;
                            }

                            TreeNode node2 = new TreeNode(funName);
                            node.Nodes.Add(node2);
                        }
                    }
                }
                tvFile.ExpandAll();
            }
        }

        private void 运行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string filePath = tvFile.SelectedNode.Text;
            string tmpfilePath = filePath.ToLower();

            try
            {
                if (tmpfilePath.Contains(".dll"))
                {
                    string[] funNames = DllnSpace.ParserDLLClass.getArrFunName(filePath);

                    for (int i = 0; i < tvFile.SelectedNode.Nodes.Count; i++)
                    {
                        TreeNode node = tvFile.SelectedNode.Nodes[i];
                        string funName = node.Text;

                        string data = txbData.Text;
                        StringBuilder retBdstr = new StringBuilder(2048);
                        int ret = CPublic.checkCard(filePath, funName, data, retBdstr);
                        rtbRetStr.Text += data + "\n";
                        if (ret == 1)
                        {
                            node.ForeColor = Color.Green;
                        }
                        else
                        {
                            node.ForeColor = Color.Red;
                            rtbRetStr.Text += retBdstr.ToString() + "\n";
                            throw new Exception("检测失败!");
                        }
                        
                    }
                }
                else if (tmpfilePath.Contains(".js"))
                {
                    ThreadParamter th = new ThreadParamter();
                    th.formArgs = this;
                    if (tmpfilePath.IndexOf(':') == -1)
                    {
                        tmpfilePath = tvFile.SelectedNode.Parent.Text + "\\" + tmpfilePath;
                    }
                    th.m_list.Add(tmpfilePath);
                    th.inData = txbData.Text;
                     
                    MyThread demo = new MyThread(th);
                    demo.Start();
                }
                else
                {
                    TreeNode node = tvFile.SelectedNode.Parent;
                    string dllPath = "";
                    if (node != null)
                    {
                        string funName = tvFile.SelectedNode.Text;
                        dllPath = node.Text;
                        //加载dll
                        string data = txbData.Text;
                        StringBuilder retBdstr = new StringBuilder(2048);
                        int ret = CPublic.checkCard(dllPath, filePath ,data, retBdstr);
                        if (ret == 1) {
                            rtbRetStr.Text = retBdstr.ToString();
                            node.ForeColor = Color.Green;
                        }
                        else {
                            tvFile.SelectedNode.ForeColor = Color.Red;
                            rtbRetStr.Text += retBdstr.ToString() + "\n";
                            throw new Exception("检测失败!");
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                rtbRetStr.Text += ex.Message + "\n";
            }
  
        }

        private void btn_解析返回数据_Click(object sender, EventArgs e)
        {
            FrmRetData frd = new FrmRetData(rtbRetStr.Text);
            frd.ShowDialog();
        }

        //private bool check = false;
        private void treeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            //通过鼠标或者键盘触发事件，防止修改节点的Checked状态时候再次进入
            if (e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard)
            {
                SetChildNodeCheckedState(e.Node, e.Node.Checked);
                SetParentNodeCheckedState(e.Node, e.Node.Checked);
            }
        }
        //设置子节点状态
        private void SetChildNodeCheckedState(TreeNode currNode, bool isCheckedOrNot)
        {
            if (currNode.Nodes == null) return; //没有子节点返回
            foreach (TreeNode tmpNode in currNode.Nodes)
            {
                tmpNode.Checked = isCheckedOrNot;
                SetChildNodeCheckedState(tmpNode, isCheckedOrNot);
            }
        }

        //设置父节点状态
        private void SetParentNodeCheckedState(TreeNode currNode, bool isCheckedOrNot)
        {
            if (currNode.Parent == null) return; //没有父节点返回
            if (isCheckedOrNot) //如果当前节点被选中，则设置所有父节点都被选中
            {
                currNode.Parent.Checked = isCheckedOrNot;
                SetParentNodeCheckedState(currNode.Parent, isCheckedOrNot);
            }
            else //如果当前节点没有被选中，则当其父节点的子节点有一个被选中时，父节点被选中，否则父节点不被选中
            {
                bool checkedFlag = false;
                foreach (TreeNode tmpNode in currNode.Parent.Nodes)
                {
                    if (tmpNode.Checked)
                    {
                        checkedFlag = true;
                        break;
                    }
                }
                currNode.Parent.Checked = checkedFlag;
                SetParentNodeCheckedState(currNode.Parent, checkedFlag);
            }
        }

        private void tvFile_AfterCheck(object sender, TreeViewEventArgs e)
        {
            //通过鼠标或者键盘触发事件，防止修改节点的Checked状态时候再次进入
            if (e.Action == TreeViewAction.ByMouse || e.Action == TreeViewAction.ByKeyboard)
            {
                SetChildNodeCheckedState(e.Node, e.Node.Checked);
                SetParentNodeCheckedState(e.Node, e.Node.Checked);
            }
        }

        private void 运行勾选ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ThreadParamter th = new ThreadParamter();
            th.formArgs = this;
            foreach (TreeNode n in tvFile.Nodes)
            {
                if (n.Checked)
                {
                    foreach (TreeNode m in n.Nodes)
                    {
                        if (m.Checked)
                        {
                            if (n.Text.ToLower().Contains(".dll"))
                            {
                                th.m_list.Add(n.Text + "," + m.Text); 
                            }
                            else
                            {
                                th.m_list.Add(n.Text + "\\" + m.Text); 
                            }
                            th.inData = txbData.Text;
                        }
                    }
                }
            }

            MyThread demo = new MyThread(th);
            demo.Start();
        }

        private void setTag(Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
                if (con.Controls.Count > 0)
                    setTag(con);
            }
        }
        private void setControls(float newx, float newy, Control cons)
        {
            foreach (Control con in cons.Controls)
            {

                string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
                float a = Convert.ToSingle(mytag[0]) * newx;
                con.Width = (int)a;
                a = Convert.ToSingle(mytag[1]) * newy;
                con.Height = (int)(a);
                a = Convert.ToSingle(mytag[2]) * newx;
                con.Left = (int)(a);
                a = Convert.ToSingle(mytag[3]) * newy;
                con.Top = (int)(a);
                Single currentSize = Convert.ToSingle(mytag[4]) * Math.Min(newx, newy);
                con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                if (con.Controls.Count > 0)
                {
                    setControls(newx, newy, con);
                }
            }

        }

        void Form1_Resize(object sender, EventArgs e)
        {
            float newx = (this.Width) / X;
            float newy = this.Height / Y;
            setControls(newx, newy, this);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Resize += new EventHandler(Form1_Resize);

            X = this.Width;
            Y = this.Height;

            setTag(this);
            Form1_Resize(new object(), new EventArgs());//x,y可在实例化时赋值,最后这句是新加的，在MDI时有用
        }

        private void btn_发送_Click(object sender, EventArgs e)
        {
            try
            {
                string text = coB_Apdu.Text;
                if (text.Length >= 10)
                {
                    string rsp = m_card.sendcmd(text);
                    printApdu(text + "=" + rsp);
                    if (!coB_Apdu.Items.Contains(text))
                    {
                        coB_Apdu.Items.Add(text);
                    }
                }

            }
            catch (System.Exception ex)
            {
                printApdu(ex.Message);
            }       
        }

        private void btn_复位_Click(object sender, EventArgs e)
        {
            try
            {
                string rsp = m_card.reset();
                printApdu( "reset=" + rsp);
            }
            catch (System.Exception ex)
            {
                printApdu(ex.Message);
            }     
        }

        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode node = tvFile.SelectedNode;
            node.Remove();
        }

        private void 打开JS文件目录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            dialog.Description = "请选择Txt所在文件夹";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (string.IsNullOrEmpty(dialog.SelectedPath))
                {
                    return;
                }
                else
                {
                    scanFile sc = new scanFile();
                    sc.ScanFiles(dialog.SelectedPath,"*.js");
                    List<string> list = sc.getList();
                    if (list.Count!=0)
                    {
                        TreeNode node = tvFile.Nodes.Add(dialog.SelectedPath);

                        for (int i = 0; i < list.Count;i++ )
                        {
                            TreeNode node2 = new TreeNode(list[i].ToString());
                            node.Nodes.Add(node2);
                        }
                    }
       
                }

            }
            
        }
    }

    public static class RichTextBoxExtension
    {
        public static void AppendTextColorful(this RichTextBox rtBox, string text, Color color, Font font, bool addNewLine = true)
        {
            if (addNewLine)
            {
                text += Environment.NewLine;
            }
            rtBox.SelectionStart = rtBox.TextLength;
            rtBox.SelectionLength = 0;
            rtBox.SelectionColor = color;
            rtBox.SelectionFont = font;
            rtBox.AppendText(text);
            rtBox.SelectionColor = rtBox.ForeColor;
        }

        public static void AppendTextColorful(this RichTextBox rtBox, string text, Color color, bool addNewLine = true)
        {
            if (addNewLine)
            {
                text += Environment.NewLine;
            }
            rtBox.SelectionStart = rtBox.TextLength;
            rtBox.SelectionLength = 0;
            rtBox.SelectionColor = color;
            rtBox.AppendText(text);
            rtBox.SelectionColor = rtBox.ForeColor;
        }
    }
}
